/**
 * UniApp WebSocket 管理器
 * 用于连接 socket-server 的原生 WebSocket 端点
 */
class WebSocketManager {
    constructor() {
        this.ws = null;
        this.isConnected = false;
        this.reconnectAttempts = 0;
        this.maxReconnectAttempts = 5;
        this.reconnectInterval = 3000;
        this.heartbeatInterval = null;
        this.messageCallbacks = new Map();
        this.eventCallbacks = new Map();
        this.serverUrl = 'ws://113.45.228.8/websocket';
    }

    /**
     * 连接WebSocket服务器
     * @param {string} url - WebSocket服务器地址
     * @returns {Promise} 连接结果
     */
    connect(url = this.serverUrl) {
        return new Promise((resolve, reject) => {
            try {
                console.log('正在连接WebSocket服务器:', url);
                
                this.ws = uni.connectSocket({
                    url: url,
                    success: () => {
                        console.log('WebSocket连接请求已发送');
                    },
                    fail: (error) => {
                        console.error('WebSocket连接失败:', error);
                        reject(error);
                    }
                });

                // 监听连接打开
                uni.onSocketOpen((res) => {
                    console.log('WebSocket连接已打开:', res);
                    this.isConnected = true;
                    this.reconnectAttempts = 0;
                    this.startHeartbeat();
                    this.emit('connection_status', { connected: true });
                    resolve(res);
                });

                // 监听连接关闭
                uni.onSocketClose((res) => {
                    console.log('WebSocket连接已关闭:', res);
                    this.isConnected = false;
                    this.stopHeartbeat();
                    this.emit('connection_status', { connected: false });
                    this.handleReconnect();
                });

                // 监听连接错误
                uni.onSocketError((res) => {
                    console.error('WebSocket连接错误:', res);
                    this.isConnected = false;
                    this.emit('connection_status', { connected: false });
                    reject(res);
                });

                // 监听消息
                uni.onSocketMessage((res) => {
                    // 减少日志输出，只在调试时显示
                    if (process.env.NODE_ENV === 'development') {
                        console.log('收到WebSocket消息:', res.data);
                    }
                    this.handleMessage(res.data);
                });

            } catch (error) {
                console.error('创建WebSocket连接时出错:', error);
                reject(error);
            }
        });
    }

    /**
     * 断开WebSocket连接
     */
    disconnect() {
        if (this.ws && this.isConnected) {
            console.log('正在断开WebSocket连接');
            this.stopHeartbeat();
            uni.closeSocket();
            this.isConnected = false;
            this.emit('connection_status', { connected: false });
        }
    }

    /**
     * 发送消息
     * @param {Object|string} message - 要发送的消息
     * @returns {boolean} 发送是否成功
     */
    send(message) {
        if (!this.isConnected) {
            console.error('WebSocket未连接，无法发送消息');
            return false;
        }

        try {
            const messageStr = typeof message === 'string' ? message : JSON.stringify(message);
            console.log('发送消息:', messageStr);
            
            uni.sendSocketMessage({
                data: messageStr,
                success: () => {
                    console.log('消息发送成功');
                },
                fail: (error) => {
                    console.error('消息发送失败:', error);
                }
            });
            return true;
        } catch (error) {
            console.error('发送消息时出错:', error);
            return false;
        }
    }

    /**
     * 发送带重试的消息
     * @param {Object|string} message - 要发送的消息
     * @param {number} maxRetries - 最大重试次数
     * @returns {Promise} 发送结果
     */
    sendWithRetry(message, maxRetries = 3) {
        let retryCount = 0;
        
        const attemptSend = () => {
            if (this.send(message)) {
                return Promise.resolve();
            } else {
                retryCount++;
                if (retryCount < maxRetries) {
                    return new Promise(resolve => {
                        setTimeout(() => {
                            attemptSend().then(resolve);
                        }, 1000 * retryCount);
                    });
                } else {
                    return Promise.reject(new Error('消息发送失败'));
                }
            }
        };
        
        return attemptSend();
    }

    /**
     * 处理接收到的消息
     * @param {string} data - 接收到的消息数据
     */
    handleMessage(data) {
        try {
            const message = JSON.parse(data);
            // 减少日志输出，只在调试时显示
            if (process.env.NODE_ENV === 'development') {
                console.log('解析消息:', message);
            }
            
            // 触发消息类型回调
            if (message.type) {
                const callback = this.messageCallbacks.get(message.type);
                if (callback) {
                    callback(message);
                }
            }
            
            // 触发事件回调
            this.emit('message', message);
            
        } catch (error) {
            console.error('解析消息时出错:', error);
            console.log('原始消息数据:', data);
        }
    }

    /**
     * 注册消息类型回调
     * @param {string} type - 消息类型
     * @param {Function} callback - 回调函数
     */
    onMessage(type, callback) {
        this.messageCallbacks.set(type, callback);
    }

    /**
     * 注册事件回调
     * @param {string} event - 事件名称
     * @param {Function} callback - 回调函数
     */
    on(event, callback) {
        if (!this.eventCallbacks.has(event)) {
            this.eventCallbacks.set(event, []);
        }
        this.eventCallbacks.get(event).push(callback);
    }

    /**
     * 取消事件回调
     * @param {string} event - 事件名称
     * @param {Function} callback - 回调函数
     */
    off(event, callback) {
        if (this.eventCallbacks.has(event)) {
            const callbacks = this.eventCallbacks.get(event);
            const index = callbacks.indexOf(callback);
            if (index > -1) {
                callbacks.splice(index, 1);
            }
        }
    }

    /**
     * 触发事件
     * @param {string} event - 事件名称
     * @param {*} data - 事件数据
     */
    emit(event, data) {
        if (this.eventCallbacks.has(event)) {
            const callbacks = this.eventCallbacks.get(event);
            callbacks.forEach(callback => {
                try {
                    callback(data);
                } catch (error) {
                    console.error('事件回调执行错误:', error);
                }
            });
        }
    }

    /**
     * 开始心跳
     */
    startHeartbeat() {
        this.stopHeartbeat(); // 先停止之前的心跳
        this.heartbeatInterval = setInterval(() => {
            this.sendHeartbeat();
        }, 30000); // 30秒发送一次心跳
        console.log('开始心跳检测');
    }

    /**
     * 停止心跳
     */
    stopHeartbeat() {
        if (this.heartbeatInterval) {
            clearInterval(this.heartbeatInterval);
            this.heartbeatInterval = null;
            console.log('停止心跳检测');
        }
    }

    /**
     * 发送心跳消息
     */
    sendHeartbeat() {
        const heartbeat = {
            timestamp: Date.now(),
            roomId: "room1" // 根据实际情况设置
        };
        console.log('发送心跳消息:', heartbeat);
        this.send(heartbeat);
    }

    /**
     * 处理重连
     */
    handleReconnect() {
        if (this.reconnectAttempts < this.maxReconnectAttempts) {
            this.reconnectAttempts++;
            console.log(`尝试重连 (${this.reconnectAttempts}/${this.maxReconnectAttempts})`);
            
            setTimeout(() => {
                this.connect().catch(error => {
                    console.error('重连失败:', error);
                });
            }, this.reconnectInterval);
        } else {
            console.error('重连次数已达上限');
            this.emit('reconnect_failed', { attempts: this.reconnectAttempts });
        }
    }

    /**
     * 处理连接错误
     * @param {Object} error - 错误信息
     */
    handleConnectionError(error) {
        console.error('WebSocket连接错误:', error);
        
        // 根据错误类型进行不同处理
        if (error.errMsg && error.errMsg.includes('timeout')) {
            uni.showToast({
                title: '连接超时，请检查网络',
                icon: 'none'
            });
        } else if (error.errMsg && error.errMsg.includes('refused')) {
            uni.showToast({
                title: '服务器拒绝连接',
                icon: 'none'
            });
        } else {
            uni.showToast({
                title: '连接失败，请重试',
                icon: 'none'
            });
        }
        
        this.emit('connection_error', error);
    }

    /**
     * 获取连接状态
     * @returns {Object} 连接状态对象 { connected: boolean }
     */
    getConnectionStatus() {
        return { connected: this.isConnected };
    }

    /**
     * 设置服务器地址
     * @param {string} url - 服务器地址
     */
    setServerUrl(url) {
        this.serverUrl = url;
    }

    /**
     * 清理资源
     */
    destroy() {
        this.disconnect();
        this.messageCallbacks.clear();
        this.eventCallbacks.clear();
        this.reconnectAttempts = 0;
    }
}

export default WebSocketManager; 